﻿/******************************
Copyright (c) 2009, Avanade
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

* Neither the name of Avanade nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
******************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using Microsoft.Samples.ServiceHosting.StorageClient;
using System.Data.Services.Client;
using System.Xml.Linq;

namespace PhpSiteGenerator
{
    public partial class PhpGenerator : Form
    {
        private string _pkColumn = String.Empty;
        private bool _dbConnectionIsLocked = false;
        private string _schemaName = String.Empty;
        private string _tableName = String.Empty;
        private StorageAccountInfo _account;
        private CssProperties _allStyles = new CssProperties();

        public PhpGenerator()
        {
            InitializeComponent();
           
            //Try to get CssProperties from config
            _allStyles = new CssProperties();

            //Set the values for listboxTag and set the defaults for the listboxTag
            //These are dynamically pulled from configuration settings in cssproperties.xml
            foreach (CssStyle style in _allStyles.Styles)
            {
                listboxCssTag.Items.Add(style.CssName);
            }
            
            listboxCssTag.SelectedIndex = 0;      
            
        }

        private void btnFindDatabases_Click(object sender, EventArgs e)
        {
            if (rbSqlDb.Checked || rbSqlAzure.Checked)
            {
                FindDatabasesSql();
            }
            else
            {
                FindTables();
            }

        }

        private void FindDatabasesSql()
        {
            //Check for lock before running a connection attempt
            if (_dbConnectionIsLocked == false)
            {
                if (validateSQLCredentials())
                {
                    //Create sql connection based on user-entered values
                    SqlConnection conn = CreateConnection(txtUsername.Text, txtPassword.Text, txtServerName.Text, "");
                    
                    if (conn != null)
                    {
                        // Change cursor
                        Cursor.Current = Cursors.WaitCursor;

                        try
                        {
                            //Open the connection
                            conn.Open();

                            //Pull list of databases using built-in stp
                            SqlCommand dbCommand = new SqlCommand();
                            dbCommand.Connection = conn;

                            dbCommand.CommandType = CommandType.Text;
                            dbCommand.CommandText = "select name from sys.databases";

                            SqlDataReader reader;
                            reader = dbCommand.ExecuteReader();

                            List<string> databases = new List<string>();

                            while (reader.Read())
                            {
                                databases.Add(reader.GetString(0));
                            }

                            // add Select... as the first item
                            databases.Insert(0, "Select Database...");

                            // Set the combobox datasource to the list
                            cmbDatabase.DataSource = databases;

                            //after successful Find Databases click lock the UI
                            lockUI();
                        }
                        catch (SqlException exc)
                        {
                            MessageBox.Show("There was an error connecting to the database server:"
                                + Environment.NewLine
                                + Environment.NewLine
                                + exc.Errors[0].Message
                                + Environment.NewLine
                                + Environment.NewLine
                                + "Please review your connection credentials and make sure the database server is available.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error );

                            //disables the button on invalid state
                            btnGenerateSite.Enabled = false;
                            btnNext.Enabled = false;
                        }
                        finally
                        {
                            conn.Close();

                            // Change cursor back
                            Cursor.Current = Cursors.Default;
                        }
                    }
                }
            }
            //Unlock the UI if it was locked on button click
            else
            {
                unlockUI();
            }
        }

        private SqlConnection CreateConnection(string user, string pass, string server, string database)
        {
            SqlConnection conn = null;

            try {
                if(database == "")
                    conn = new SqlConnection(String.Format("server={0};uid={1};pwd={2}", server, user, pass));
                else
                    conn = new SqlConnection(String.Format("server={0};uid={1};pwd={2};Initial Catalog={3}", server, user, pass, database));
            }
            catch(Exception exc)
            {
                MessageBox.Show("There was an error connecting to the database server:"
                           + Environment.NewLine
                           + Environment.NewLine
                           + exc.Message
                           + Environment.NewLine
                           + Environment.NewLine
                           + "Please review your connection credentials and make sure the database server is available.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return conn;
        }

        private void cmbDatabase_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbTable.DataSource = null;
            cmbTable.Items.Clear();
            chxLbColumns.Items.Clear();

            //make sure there is a valid item selection
            if(cmbDatabase.SelectedItem != null && cmbDatabase.SelectedIndex != 0)
            {
                //Create sql connection based on user-entered values, adding newly selected database
                SqlConnection conn = CreateConnection(txtUsername.Text, txtPassword.Text, txtServerName.Text, cmbDatabase.SelectedItem.ToString());

                if (conn != null)
                {
                    string selectText;
                    DataSet tablesDS = new DataSet();

                    // display busy cursor for database operations
                    Cursor.Current = Cursors.WaitCursor;

                    //Create sql connection based on user-entered values, adding newly selected database
                    try
                    {
                        conn = new SqlConnection(String.Format("server={0};uid={1};pwd={2};Initial Catalog={3}", txtServerName.Text, txtUsername.Text, txtPassword.Text, cmbDatabase.SelectedItem));

                        //Open the connection
                        conn.Open();

                        //Pull the list of tables in the database using the INFORMATION_SCHEMA 
                        SqlDataAdapter adapter = new SqlDataAdapter();

                        selectText = "select s.name table_schema, t.name table_name from sys.tables t inner join sys.schemas s on t.schema_id = s.schema_id";

                        adapter.SelectCommand = new SqlCommand(selectText, conn);

                        // Fill the dataset with the values returned from the select query
                        adapter.Fill(tablesDS, "databaseTables");

                        DataTable tables = tablesDS.Tables[0];

                        if (tables.Rows.Count > 0)
                        {
                            // Loop through all rows and concat schema + table in schema column which is needed for the generated PHP queries
                            foreach (DataRow row in tables.Rows)
                            {
                                row[0] = row[0] + "." + row[1];
                            }

                            // Add a "Select Table..." to the first row of the datatable
                            DataRow newTablesRow = tables.NewRow();
                            newTablesRow[0] = "";
                            newTablesRow[1] = "Select Table...";

                            tables.Rows.InsertAt(newTablesRow, 0);

                            // Display the simple table name (minus the schema)
                            cmbTable.DisplayMember = tables.Columns[1].ToString();
                            cmbTable.ValueMember = tables.Columns[0].ToString();

                            // set the combobox datasource to the datatable
                            cmbTable.DataSource = tables;
                        }
                    }
                    catch (SqlException exc)
                    {
                        MessageBox.Show("There was an error selecting the database:"
                            + Environment.NewLine
                            + Environment.NewLine
                            + exc.Errors[0].Message
                            + Environment.NewLine
                            + Environment.NewLine
                            + "Please select a different database.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                        //disables the button on invalid state
                        btnGenerateSite.Enabled = false;
                        btnNext.Enabled = false;
                    }
                    finally
                    {
                        conn.Close();

                        // restore cursor to default
                        Cursor.Current = Cursors.Default;
                    }
                }
            }
        }

        private void cmbTable_SelectedIndexChanged(object sender, EventArgs e)
        {
            // display wait cursor during database operation
            Cursor.Current = Cursors.WaitCursor;

            chxLbColumns.Items.Clear();

            //make sure there is a valid item selection first
            if (cmbTable.SelectedItem != null && !String.IsNullOrEmpty(cmbTable.SelectedItem.ToString()))
            {
                if ((rbSqlDb.Checked || rbSqlAzure.Checked) && cmbTable.SelectedIndex > 0)
                {
                    string pkCommand;

                    //Create sql connection based on user-entered values, adding newly selected database
                    SqlConnection conn = CreateConnection(txtUsername.Text, txtPassword.Text, txtServerName.Text, cmbDatabase.SelectedItem.ToString());

                    if (conn != null)
                    {
                        try
                        {
                            //Open the connection
                            conn.Open();

                            //First determine the primary key for this table, if one doesn't exist, display error
                            SqlCommand pkDbCommand = new SqlCommand();
                            pkDbCommand.Connection = conn;
                            pkDbCommand.CommandType = CommandType.Text;

                            pkCommand = @"select c.name from sys.tables t 
                               join sys.schemas s on s.schema_id = t.schema_id 
                               join sys.indexes i on t.object_id = i.object_id 
                               join sys.index_columns ic on i.object_id = ic.object_id and i.index_id = ic.index_id 
                               join sys.columns c on ic.object_id = c.object_id and ic.column_id = c.column_id 
                               where is_primary_key = 1 and t.name = '{0}'";

                            pkDbCommand.CommandText = String.Format(pkCommand, cmbTable.Text.ToString());

                            //If this returns nothing, the table is invalid
                            SqlDataReader pkReader = pkDbCommand.ExecuteReader();

                            List<string> pks = new List<string>();

                            while (pkReader.Read())
                            {
                                pks.Add(pkReader.GetString(0));
                            }

                            pkReader.Close();

                            if (pks.Count == 0)
                            {
                                //Display invalid table to the user
                                MessageBox.Show("The selected table is invalid.  No Primary Key exists", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                btnGenerateSite.Enabled = false;
                                btnNext.Enabled = false;
                                return;
                            }
                            else
                            {
                                btnGenerateSite.Enabled = true;
                                btnNext.Enabled = true;
                                
                            }

                            //Select the available columns in the table
                            SqlCommand dbCommand = new SqlCommand();
                            dbCommand.Connection = conn;
                            dbCommand.CommandType = CommandType.Text;

                            dbCommand.CommandText = String.Format("select c.name from sys.columns c inner join sys.tables t on c.object_id = t.object_id where t.name = '{0}'", cmbTable.Text.ToString());

                            SqlDataReader reader;
                            reader = dbCommand.ExecuteReader();

                            List<string> columns = new List<string>();

                            while (reader.Read())
                            {
                                columns.Add(reader.GetString(0));
                            }

                            //Add the columns to the checked listbox control
                            chxLbColumns.Items.AddRange(columns.ToArray());

                            if (pks.Count > 0)
                            {
                                //If we have a primary key, select it by default
                                chxLbColumns.SetItemChecked(chxLbColumns.Items.IndexOf(pks.First()), true);
                                _pkColumn = pks.First();
                            }
                        }
                        catch (SqlException exc)
                        {
                            MessageBox.Show("There was an error selecting the table:"
                                + Environment.NewLine
                                + Environment.NewLine
                                + exc.Errors[0].Message
                                + Environment.NewLine
                                + Environment.NewLine
                                + "Please select a different table.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                            //disables the button on invalid state
                            btnGenerateSite.Enabled = false;
                            btnNext.Enabled = false;
                        }
                        finally
                        {
                            conn.Close();

                            // revert cursor to default
                            Cursor.Current = Cursors.Default;
                        }
                    }
                }
                if (rbAzureStorage.Checked)
                {
                    FillColumnTable(cmbTable.SelectedItem.ToString());
                    btnGenerateSite.Enabled = true;
                    btnNext.Enabled = true;
                }     
            }
        }

        private void btnGenerateSite_Click(object sender, EventArgs e)
        {
            //Check logic for paging, needs an int value if pagin is checked otherwise 0
            int numberOfRowsPerPage = 0;
            if (chxPaging.Checked)
            {
                try
                {
                    numberOfRowsPerPage = Convert.ToInt16(txtNumRows.Text);                  
                }
                catch
                {
                    MessageBox.Show("If paging is checked you must enter a number of rows per page.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }

            // Make sure user has selected a UI option, if not prompt
            if (!rbHTML.Checked && !rbSilverlight.Checked)
            {
                MessageBox.Show("Please select a User Interface Option.");
                return;
            }

            FolderBrowserDialog fbd = new FolderBrowserDialog();

            if (fbd.ShowDialog() == DialogResult.OK)
            {
                //Create DatabaseInfo object to be used by the SiteGenerator class and set its properties
                DatabaseInfo configuredDb = new DatabaseInfo();
                configuredDb.UserName = txtUsername.Text;
                configuredDb.Password = txtPassword.Text;
                configuredDb.ServerName = txtServerName.Text;
                if (rbAzureStorage.Checked)
                {
                    configuredDb.AzureAccount = txtAccountName.Text ;
                    configuredDb.AzureKey= txtSharedKey.Text;
                    configuredDb.AzureTable = cmbTable.SelectedItem.ToString() ;
                    configuredDb.AzureURI = txtEndPoint.Text;
                    configuredDb.UseProxy = chkProxy.Checked;
                    configuredDb.Host = txtHost.Text;
                    configuredDb.Port = txtPort.Text;
                    configuredDb.Credentials = txtCredential.Text;

                }
                else
                {
                    configuredDb.DatabaseName = cmbDatabase.SelectedItem.ToString();
                    configuredDb.TableName = cmbTable.SelectedValue.ToString();
                }
                configuredDb.PKColumn = _pkColumn;
                configuredDb.SaveFilesDir = fbd.SelectedPath;

                configuredDb.EnablePaging = chxPaging.Checked;
                configuredDb.EnableSorting = chxSorting.Checked;
                configuredDb.NumberOfRowsPerPage = numberOfRowsPerPage;

                //Build list of checked columns
                List<string> checkedColumns = new List<string>();
                foreach (object checkedItem in chxLbColumns.CheckedItems)
                {
                    checkedColumns.Add(checkedItem.ToString());
                }

                // Populate a list of the table column datatypes
                if (rbAzureStorage.Checked)
                {
                    configuredDb.Columns = new List<TableColumn>(10);

                    foreach (string c in checkedColumns)
                    {
                        TableColumn col = new TableColumn();
                        col.ColumnName = c;
                        col.ColumnType = "nvarchar";
                        configuredDb.Columns.Add(col);      
                    }
                  
                   
                }
                else
                {
                    configuredDb.Columns = SetColumnDataTypes(checkedColumns);
                }
                //Generate the pages
                try
                {
                    if (rbAzureStorage.Checked)
                    {
                        // based on user selection, create a Silverlight or HTML UI
                        if (rbHTML.Checked)
                        {
                            TSSiteGenerator.GenerateSite(configuredDb, _allStyles);
                        }
                        if (rbSilverlight.Checked)
                        {
                            TSSLSiteGenerator.GenerateSite(configuredDb);
                        }
                    }
                    else
                    {
                        // based on user selection, create a Silverlight or HTML UI
                        if (rbHTML.Checked)
                        {
                            SiteGenerator.GenerateSite(configuredDb, _allStyles);
                        }
                        if (rbSilverlight.Checked)
                        {
                            SLSiteGenerator.GenerateSite(configuredDb);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("There was an error generating the PHP CRUD Application: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // Display a success message
                MessageBox.Show("PHP CRUD Application successfully created!", "Congratulation", MessageBoxButtons.OK, MessageBoxIcon.Information );
            }
        }

        // Helper method to set datatypes of columns in the selected table
        private List<TableColumn> SetColumnDataTypes(List<string> columns)
        {
            List<TableColumn> checkedColumns = new List<TableColumn>();
            SqlConnection conn;

            // make sure there is a valid item selection first
            if (cmbTable.SelectedItem != null )
            {
                //Create sql connection based on user-entered values, adding newly selected database
                conn = CreateConnection(txtUsername.Text, txtPassword.Text, txtServerName.Text, cmbDatabase.SelectedItem.ToString());

                if (conn != null)
                {
                    try
                    {
                        // open the connection
                        conn.Open();

                        // get table column types for each column in columns
                        SqlCommand getColumnTypesCommand = new SqlCommand();
                        getColumnTypesCommand.Connection = conn;
                        getColumnTypesCommand.CommandType = CommandType.Text;
                        string getDTCommand;

                        getDTCommand = @"select c.name column_name, types.name data_type from sys.columns c
                                    inner join sys.tables t on c.object_id = t.object_id 
                                    inner join sys.types types on c.user_type_id = types.user_type_id
                                    where t.name = '{0}'";

                        getColumnTypesCommand.CommandText = String.Format(getDTCommand, cmbTable.Text.ToString());

                        SqlDataReader dtReader = getColumnTypesCommand.ExecuteReader();

                        // iterate through the tables columns
                        while (dtReader.Read())
                        {
                            // if this column exists in the selected columns list, create a table column object
                            string colName = (String)dtReader.GetValue(0);
                            if (columns.Contains(colName))
                            {
                                TableColumn col = new TableColumn();
                                col.ColumnName = dtReader[0].ToString();
                                col.ColumnType = dtReader[1].ToString();
                                checkedColumns.Add(col);
                            }
                        }
                    }
                    catch (SqlException exc)
                    {
                        MessageBox.Show("There was an error selecting the table:"
                            + Environment.NewLine
                            + Environment.NewLine
                            + exc.Errors[0].Message
                            + Environment.NewLine
                            + Environment.NewLine
                            + "Please select a different table.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                        //disables the button on invalid state
                        btnGenerateSite.Enabled = false;
                        btnNext.Enabled = false;
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }

            return checkedColumns;

        }

        private void listboxTag_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Set the datasource of the datagridview based on the selected item in listboxCssTag
            cssDataGridView.DataSource = _allStyles.Styles[listboxCssTag.SelectedIndex].CssProperties;
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            bool valid = true;

            if (rbSqlAzure.Checked || rbSqlDb.Checked)
            {
                // Verify that the primary key is selected
                for (int i = 0; i < chxLbColumns.Items.Count-1; i++)
                {
                    if (chxLbColumns.Items[i].ToString() == _pkColumn && !chxLbColumns.GetItemChecked(i))
                    {
                        MessageBox.Show(string.Format("You must select the primary key of the table ({0})",
                            _pkColumn), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        valid = false;
                    }
                }
            }
            else
            {
                if (chxLbColumns.CheckedItems.Count == 0)
                {
                    MessageBox.Show("You must select at least one column", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    valid = false;
                }
            }

            if(valid)
            {
                pnlDisplay.Visible = true;
                pnlDatabase.Visible = false;
            }
        }

        private void chxPaging_CheckedChanged(object sender, EventArgs e)
        {
            lblRowsPerPage.Enabled = txtNumRows.Enabled = chxPaging.Checked;
        }

        private void btnPrevious_Click(object sender, EventArgs e)
        {
            pnlDisplay.Visible = false;
            pnlDatabase.Visible = true;
        }


        private void cssDataGridView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            //Adds the different valid values as drop down menus in the data-grid
            if (e.RowIndex == 1)
            {
                for (int i = 0; i <= e.RowCount; i++)
                {

                    DataGridViewComboBoxCell cc = new DataGridViewComboBoxCell();
                    cc.DataSource = _allStyles.Styles[listboxCssTag.SelectedIndex].CssProperties[i].ValidValues;

                    cssDataGridView[1, i] = cc;
                }

            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            MessageBoxButtons buttons = MessageBoxButtons.OKCancel;
            DialogResult result;

            // Double check that user really wants to exit... just in case they accidentally hit exit instead of generate site
            result = MessageBox.Show("Are you sure you want to exit?", "Exit Confirmation", buttons,MessageBoxIcon.Question );

            if (result == DialogResult.OK)
            {
                Application.Exit();
            }
        }

        private void rbSilverlight_CheckedChanged(object sender, EventArgs e)
        {
            // if Silverlight rb is checked, disable the cssDataGridView StyleChanged groupbox
            grpCss.Enabled = rbHTML.Checked;
        }

        private void rbSqlDb_CheckedChanged(object sender, EventArgs e)
        {
            if (rbSqlDb.Checked)
            {
                pnlSqlDb.Visible = true;
                lblDatabase.Visible = true;
                cmbDatabase.Visible = true;
                btnFindDatabases.Text = "Find databases";
                chxSorting.Enabled = true;
                chxPaging.Enabled = true;
            }
            else
            {
                pnlSqlDb.Visible = false;
            }
        }

        private void rbAzureStorage_CheckedChanged(object sender, EventArgs e)
        {
            if (rbAzureStorage.Checked)
            {
                pnlAzureStorage.Visible = true;
                lblDatabase.Visible = false;
                cmbDatabase.Visible = false;
                btnFindDatabases.Text = "Find tables";

                // Disable paging and sorting for Azure storage
                chxSorting.Enabled = false;
                chxPaging.Enabled = false;
                chxSorting.Checked = false;
                chxPaging.Checked = false;
                txtNumRows.Text = "";
            }
            else
            {
                pnlAzureStorage.Visible = false;
            }
        }

        private void rbSqlAzure_CheckedChanged(object sender, EventArgs e)
        {
            if (rbSqlAzure.Checked)
            {
                pnlSqlDb.Visible = true;
                lblDatabase.Visible = true;
                cmbDatabase.Visible = true;
                btnFindDatabases.Text = "Find databases";
                chxSorting.Enabled = true;
                chxPaging.Enabled = true;
            }
            else
            {
                pnlSqlDb.Visible = false;
            }
        }

        private void FindTables()
        {
            if (!_dbConnectionIsLocked)
            {
                if (validateAzureStorageCredentials())
                {
                    // Change cursor
                    Cursor.Current = Cursors.WaitCursor;

                    try
                    {
                        _account = new StorageAccountInfo(new Uri("http://" + txtEndPoint.Text), null, txtAccountName.Text, txtSharedKey.Text);
                        TableStorage t = TableStorage.Create(_account);
                        IEnumerable<string> table = t.ListTables();

                        cmbTable.DataSource = null;
                        cmbTable.Items.Clear();

                        cmbTable.Text = "Select Table...";
                      
                        foreach (string ss in table)
                            cmbTable.Items.Add(ss);

                        //after successful Find tables click lock the UI
                        lockUI();
                    }
                    catch (Exception exc)
                    {
                        MessageBox.Show("Connection error :"
                            + Environment.NewLine
                            + Environment.NewLine
                            + exc.Message
                            + Environment.NewLine
                            + Environment.NewLine
                            + "Please review your connection credentials and make sure the database server is available.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                        btnNext.Enabled = false;
                    }

                    finally
                    {
                        // revert cursor to default
                        Cursor.Current = Cursors.Default;
                    }

                    btnNext.Enabled = true;
                }
            }
            //Unlock the UI if it was locked on button click
            else
            {
                unlockUI();
            }
        }

        private bool validateAzureStorageCredentials()
        {
            bool valid = true;
            string message = "";

            if (txtAccountName.Text == "")
            {
                message = "You must enter an account name\n";
                valid = false;
            }
            if (txtSharedKey.Text == "")
            {
                message += "You must enter a shared key\n";
                valid = false;
            }
            if (txtEndPoint.Text == "")
            {
                message += "You must enter a table storage endpoint";
                valid = false;
            }

            if (!valid)
                MessageBox.Show(message);

            return valid;
        }

        private bool validateSQLCredentials()
        {
            bool valid = true;
            string message = "";

            if (txtUsername.Text == "")
            {
                message = "You must enter a user name\n";
                valid = false;
            }
            else if (rbSqlAzure.Checked)
            {
                string[] separator = { "@" };

                // This user name format is needed for the connection in PHP
                if (txtUsername.Text.Split(separator, StringSplitOptions.RemoveEmptyEntries).Count() != 2)
                {
                    message = "The user name must be in that format : userName@serverName\n";
                    valid = false;
                }
            }
            if (txtPassword.Text == "")
            {
                message += "You must enter a password\n";
                valid = false;
            }
            if (txtServerName.Text == "")
            {
                message += "You must enter a server name";
                valid = false;
            }

            if (!valid)
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            return valid;
        }

        private void lockUI()
        {
            _dbConnectionIsLocked = true;
            btnFindDatabases.Text = "Reset Connection";

            txtUsername.Enabled = false;
            txtServerName.Enabled = false;
            txtPassword.Enabled = false;
            txtAccountName.Enabled = false;
            txtSharedKey.Enabled = false;
            txtEndPoint.Enabled = false;
            rbSqlDb.Enabled = false;
            rbSqlAzure.Enabled = false;
            rbAzureStorage.Enabled = false;
            txtHost.Enabled = false;
            lblHost.Enabled = false;
            txtPort.Enabled = false;
            lblPort.Enabled = false;
            txtCredential.Enabled = false;
            lblCredential.Enabled = false;
        }

        private void unlockUI()
        {
            _dbConnectionIsLocked = false;
            btnFindDatabases.Text = "Find Databases";

            txtUsername.Enabled = true;
            txtServerName.Enabled = true;
            txtPassword.Enabled = true;
            btnGenerateSite.Enabled = false;
            txtAccountName.Enabled = true;
            txtSharedKey.Enabled = true;
            txtEndPoint.Enabled = true;
            rbSqlDb.Enabled = true;
            rbSqlAzure.Enabled = true;
            rbAzureStorage.Enabled = true;
            txtHost.Enabled = true;
            lblHost.Enabled = true;
            txtPort.Enabled = true;
            lblPort.Enabled = true;
            txtCredential.Enabled = true;
            lblCredential.Enabled = true;
            btnNext.Enabled = true;

            cmbTable.DataSource = null;
            cmbTable.Items.Clear();
            cmbTable.Text = "";
            cmbDatabase.DataSource = null;
            chxLbColumns.Items.Clear();
        }

        // Get the columns for a table and populate the column object for the Azure storage option
        private void FillColumnTable(string tableName)
        {
            try
            {
                TableStorageDataServiceContext ds = new TableStorageDataServiceContext(_account);

                // The only way we found to dynamically get columns is to intercept the Atom XML file
                // and extract the properties of the table
                ds.IgnoreMissingProperties = true;
                ds.ReadingEntity += new EventHandler<ReadingWritingEntityEventArgs>(GetColumns);
                foreach (var item in ds.CreateQuery<GenericStorage>(tableName).Take(1)) { }
            }
            catch (SqlException exc)
            {
                MessageBox.Show("There was an error selecting the table:"
                        + Environment.NewLine
                        + Environment.NewLine
                        + exc.Errors[0].Message
                        + Environment.NewLine
                        + Environment.NewLine
                        + "Please select a different table.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                btnNext.Enabled = false;
            }

            btnNext.Enabled = true;
        }

        private void GetColumns(object sender, ReadingWritingEntityEventArgs e)
        {
            var result = from el in e.Data.Elements().Elements().Elements()
                         where el.Name.LocalName != "PartitionKey" && el.Name.LocalName != "RowKey" && el.Name.LocalName != "Timestamp"
                         select el.Name.LocalName;

            foreach (string xEle in result)
                chxLbColumns.Items.Add(xEle);
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void chkProxy_CheckedChanged(object sender, EventArgs e)
        {
            bool enabled = chkProxy.Checked;
            txtHost.Enabled = enabled;
            lblHost.Enabled = enabled;
            txtPort.Enabled = enabled;
            lblPort.Enabled = enabled;
            txtCredential.Enabled = enabled;
            lblCredential.Enabled = enabled;

        }
    }
}
